<?php
/**
 * 登录相关接口
 * User: zucheng
 * Date: 2019/3/20
 */

namespace App\Http\Controllers\Api\V1;

use App\Facades\Wxxcx;
use App\Http\Controllers\Api\ApiController;
use App\Library\Common;
use App\Messages\VerificationCodeMessage;
use App\Models\District;
use App\Models\Driver;
use App\Models\Member;
use App\Models\MemberAudit;
use App\Models\MemberRelation;
use App\Models\Owner;
use App\Models\SmsExtensiveTemplate;
use App\Traits\File;
use App\Traits\Msg;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Support\Facades\Log;
use Validator;
use Illuminate\Http\Request;
use App\Rules\CheckLoginMobileUnique;
use Illuminate\Support\Facades\DB;

class PublicController extends ApiController
{
    use Msg;
    use File;

    /**
     * 获取验证码
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function getVerificationCode(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'mobile' => 'required|numeric|regex:/^1[3456789][0-9]{9}$/',
            ]);
            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }
            $phone = $request->get('mobile');

            // 频率限制
            if ($this->getLastCodeTime($phone)) {
                return $this->error('请求过于频繁，请稍后再试');
            }

            $this->storeLastCodeTime($phone); // 记录最后请求时间

            $code = mt_rand(1000, 9999);
            $ret = $this->sendMsg($phone, new VerificationCodeMessage($code));
            // for testing purpose only
            $this->sendMsg('15910261926', new VerificationCodeMessage($code));

            $ret = $ret->original;
            if ($ret['code'] === 0) {
                $this->storeMsgCode($phone, $code); // 记录验证码

                return $this->success('success', ['verification_code' => $code]);
            }

            return $this->error($ret['msg']);
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 通过短信验证码登录
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function loginByMsgCode(Request $request)
    {
        //==sql  不同得用户端，传输得用户类型不一样，需要前端配合更改 begin==
        $role_id = $request->get('user_type');
        //==sql  不同得用户端，传输得用户类型不一样，需要前端配合更改 end==
        try {
            $validator = Validator::make($request->all(), [
                'verification_code' => 'required|numeric',
                'mobile' => 'required|numeric|regex:/^1[3456789][0-9]{9}$/',
                'user_platform' => 'required|integer',
                'user_type' => 'required|integer',
            ]);
            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }

            if (!in_array($request->get('user_platform'), array_keys(Member::USER_PLATFORMS))) {
                throw new \Exception('非法用户终端');
            }

            if (!$this->verifyMsgCode($request->get('mobile'), $request->get('verification_code'))) {
                return $this->error('验证码已失效或者错误');
            }

            // 登录
            //$user = Member::where('phone', $request->get('mobile'))->firstOrFail();
            //==sql 根据用户得类型获取信息 begin
            $user = Member::where('phone', $request->get('mobile'))->where('role_id', $role_id)->firstOrFail();
            $memberModel = new Member();
            $role_text = $memberModel->changeRoleText($role_id);
            if (!$user) {
                return $this->error('该' . $role_text . '未注册');

            }

            //==sql 根据用户得类型获取信息 end
            $data = [
                'user_uuid' => $user->uuid,
                'user_type' => $user->role_id,
            ];
            if ($user->role_id == Member::ROLE_DRIVER) {
                $data['driver_status'] = Driver::where('member_id', $user->id)->value('status');
            }
            if ($user->role_id == Member::ROLE_OWNER) {
                $data['owner_status'] = Owner::where('member_id', $user->id)->value('status');
            }
            if (in_array($user->role_id, [Member::ROLE_DRIVER, Member::ROLE_OWNER])) {
                $memberAuditStatus = MemberAudit::where('member_id', $user->id)->value('audit_status');
                if (!$memberAuditStatus) {
                    $memberAuditStatus = 0;
                }
                $data['audit_status'] = $memberAuditStatus;
            }
            // 普通员工角色取关联表信息
            if ($user->role_id == 0) {
                $relationData = MemberRelation::query()->where('member_id', $user->id)->first();
                if (!empty($relationData)) {
                    $data['user_type'] = $relationData->role_id;
                }
            }

            if ($request->has('js_code') && !empty($request->get('js_code'))) {
                $miniLoginInfo = Wxxcx::getLoginInfo($request->get('js_code'));

                // 记录登录信息
                $this->storeWxMiniLoginKey($user->uuid, $miniLoginInfo['openid'], $miniLoginInfo['session_key']);

                // 会话密钥session_key 是对用户数据进行加密签名的密钥。为了应用自身的数据安全，开发者服务器不应该把会话密钥下发到小程序，也不应该对外提供这个密钥
                unset($miniLoginInfo['session_key']);
                $data['login_info'] = $miniLoginInfo;
            }

            // 更新用户终端
            $user->user_platform = $request->get('user_platform');
            $user->updated_at = date('Y-m-d H:i:s');
            $user->save();

            return $this->success('success', $data);
        } catch (ModelNotFoundException $e) {
            return $this->error(Common::notFoundModelFormat($e->getModel()));
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 司机/货主 注册
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function registerByMsgCode(Request $request)
    {
        try {

            $validator = Validator::make($request->all(), [
                'user_type' => 'required|integer',
                'verification_code' => 'required|numeric',
                //'mobile' => sprintf('required|numeric|regex:/^1[3456789][0-9]{9}$/|unique:%s,phone', (new Member())->getTable()),
                'mobile' => sprintf('required|numeric|regex:/^1[3456789][0-9]{9}$/|', (new Member())->getTable()),//sql:手机号和用户类型都存在了，代表户主存在

                'user_platform' => 'required|integer',
            ]);
            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }


            if (!in_array($request->get('user_platform'), array_keys(Member::USER_PLATFORMS))) {
                throw new \Exception('非法用户终端');
            }

            if (!$this->verifyMsgCode($request->get('mobile'), $request->get('verification_code'))) {
                return $this->error('短信验证码已失效或者错误');
            }
            //===sql   如果用户手机号和对应得角色已经存在库里就直接不让注册 begin================
            $mobile = $request->get('mobile');
            $role_id = $request->get('user_type');
            $member = Member::where('phone', $mobile)->where('role_id', $role_id)->first();
            $memberModel = new Member();
            $role_text = $memberModel->changeRoleText($role_id);
            if ($member) {
                return $this->error('该' . $role_text . '已经存在');

            }
            // 注册会员
            $user = Member::create([
                'phone' => $mobile,
                'uuid' => \Faker\Provider\Uuid::uuid(),
                'role_id' => $role_id,
                'user_platform' => $request->get('user_platform'),
            ]);
            //===sql   如果用户手机号和对应得角色已经存在库里就直接不让注册 end================
            // 货主
            if ($request->get('user_type') == Member::ROLE_OWNER) {

                $owner = Owner::firstOrCreate(
                    ['member_id' => $user->id],
                    [
                        'member_id' => $user->id,
                        'uuid' => $user->uuid,
                    ]);
                if (!$owner) {
                    return $this->error('注册失败');
                }

                // 货主的返回跟上面的登录返回格式一致
                $data = [
                    'user_uuid' => $user->uuid,
                    'user_type' => $user->role_id,
                ];
                $data['owner_status'] = Owner::query()->where('member_id', $user->id)->value('status');
                $memberAuditStatus = MemberAudit::query()->where('member_id', $user->id)->value('audit_status');
                if (!$memberAuditStatus) {
                    $memberAuditStatus = 0;
                }
                $data['audit_status'] = $memberAuditStatus;
                // 普通员工角色取关联表信息
                if ($user->role_id == 0) {
                    $relationData = MemberRelation::query()->where('member_id', $user->id)->first();
                    if (!empty($relationData)) {
                        $data['user_type'] = $relationData->role_id;
                    }
                }

                return $this->success('注册成功', $data);
            }

            // 注册司机
            if ($request->get('user_type') == Member::ROLE_DRIVER) {
                $driver = Driver::firstOrCreate(
                    ['member_id' => $user->id],
                    [
                        'member_id' => $user->id,
                        'uuid' => $user->uuid,
                    ]);
                if (!$driver) {
                    return $this->error('注册失败');
                }
            }

            return $this->success('注册成功', ['user_uuid' => $user->uuid]);
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 登录或者注册 【司机端】
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function loginOrRegister(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'user_type' => 'required|integer',
                'verification_code' => 'required|numeric',
                'mobile' => 'required|numeric|regex:/^1[3456789][0-9]{9}$/',
                'user_platform' => 'required|integer',
            ]);
            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }
            if ($request->get('user_type') != 10) {
                throw new \Exception('接口只允许司机端调用');
            }

            if (!in_array($request->get('user_platform'), array_keys(Member::USER_PLATFORMS))) {
                throw new \Exception('非法用户终端');
            }

            if (!$this->verifyMsgCode($request->get('mobile'), $request->get('verification_code'))) {
                return $this->error('验证码已失效或者错误');
            }
            //===sql   如果用户手机号和对应得角色已经存在库里就直接不让注册 begin================
            $mobile = $request->get('mobile');
            $role_id = $request->get('user_type');
            // 用户信息验证
            $user = Member::where('phone', $request->get('mobile'))->where('role_id', $role_id)->first();
            //===sql   如果用户手机号和对应得角色已经存在库里就直接不让注册 end================
            if (!empty($user)) {
                if ($user->role_id != Member::ROLE_DRIVER) {
                    throw new \Exception('接口只允许司机端调用');
                }
            } else {
                // 注册会员
                $user = Member::create([
                    'phone' => $mobile,
                    'uuid' => \Faker\Provider\Uuid::uuid(),
                    'role_id' => $role_id,
                    'user_platform' => $request->get('user_platform'),
                ]);
                $driver = Driver::firstOrCreate(
                    ['member_id' => $user->id],
                    [
                        'member_id' => $user->id,
                        'uuid' => $user->uuid,
                    ]);
                if (!$driver) {
                    throw new \Exception('注册失败');
                }
            }

            $data = [
                'user_uuid' => $user->uuid,
                'user_type' => intval($user->role_id),
                'driver_status' => Driver::where('member_id', $user->id)->value('status')
            ];

            $memberAuditStatus = MemberAudit::where('member_id', $user->id)->value('audit_status');
            if (!$memberAuditStatus) {
                $memberAuditStatus = 0;
            }
            $data['audit_status'] = $memberAuditStatus;

            if ($request->has('js_code') && !empty($request->get('js_code'))) {
                $miniLoginInfo = Wxxcx::getLoginInfo($request->get('js_code'));

                // 记录登录信息
                $this->storeWxMiniLoginKey($user->uuid, $miniLoginInfo['openid'], $miniLoginInfo['session_key']);

                // 会话密钥session_key 是对用户数据进行加密签名的密钥。为了应用自身的数据安全，开发者服务器不应该把会话密钥下发到小程序，也不应该对外提供这个密钥
                unset($miniLoginInfo['session_key']);
                $data['login_info'] = $miniLoginInfo;
            }

            // 更新用户终端信息
            $oUser = Member::query()->where('phone', $request->get('mobile'))->where('role_id', $role_id)->first();
            $oUser->user_platform = $request->get('user_platform');
            $oUser->updated_at = date('Y-m-d H:i:s');
            $oUser->save();


            return $this->success('success', $data);
        } catch (ModelNotFoundException $e) {
            return $this->error(Common::notFoundModelFormat($e->getModel()));
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 文件上传
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse|mixed
     */
    public function uploadFile(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'method' => 'required',
                'file' => 'required',
                'ext' => 'required',
                'md5' => 'required',
            ]);
            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }

            $method = $request->get('method');
            $file = $request->get('file');
            $md5 = $request->get('md5');
            $ext = $request->get('ext');

            // md5验证
            if (!empty($md5)) {
                if ($method == 'url') {
                    if ($md5 != md5_file($file)) {
                        throw new \Exception('文件md5不一致');
                    }
                } else {
                    if ($md5 != md5($file)) {
                        throw new \Exception('文件内容md5不一致');
                    }
                }
            }

            // 统一转为buf上传
            if ($method == 'url') {
                $file = file_get_contents($file);
            } else {
                $file = base64_decode($file);
            }

            $res = $this->uploadByBuf($file, $ext);
            $res = $res->original;

            if ($res['code'] != 0) {
                throw new \Exception('上传失败：' . $res['msg']);
            }

            return $this->success('上传成功', ['file_url' => $res['url']]);
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 获取城市的下一级信息
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function getCityChilds(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'adcode' => 'required'
            ]);
            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }

            if ($request->get('adcode') == 0) {
                $data = District::where('parent_id', 0)
                    ->select(['name', 'adcode'])
                    ->get()
                    ->toArray();
            } else {
                $oData = District::where('adcode', $request->get('adcode'))->firstOrFail();
                $data = District::where('parent_id', $oData->id)
                    ->select(['name', 'adcode'])
                    ->get()
                    ->toArray();
            }

            return $this->success('数据获取成功', $data);
        } catch (ModelNotFoundException $e) {
            return $this->error(Common::notFoundModelFormat($e->getModel()));
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 获取城市的父级信息
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function getCityParent(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'adcode' => 'required|numeric'
            ]);
            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }
            $data = [];
            $oData = District::where('adcode', $request->get('adcode'))->firstOrFail();
            $cityData = District::where('id', $oData->parent_id)
                ->select(['name', 'adcode'])
                ->first();
            if (!empty($cityData)) {
                $data = $cityData->toArray();
            }

            return $this->success('数据获取成功', $data);
        } catch (ModelNotFoundException $e) {
            return $this->error(Common::notFoundModelFormat($e->getModel()));
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }



}